﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace JOATServer.SocietyFramework.Core.XML
{
    /// <summary>
    /// Extension of the BaseXMLAutomaton which implements the deserialization operations.
    /// It uses an XmlReader parser for deserialization.<br/>
    /// Author: Micu Andrei
    /// </summary>
    public partial class XMLAutomaton : BaseXMLAutomaton
    {
        protected static readonly string AUTOMATON_TAG = "automaton";
	    protected static readonly string CURRENT_MESSAGE_TAG = "current_message";
	    protected static readonly string MESSAGE_LIST_TAG = "message_list";
        protected static readonly string MESSAGE_TAG = "message";
        protected static readonly string VARIABLES_TAG = "variables";
        protected static readonly string VARIABLE_TAG = "variable";
        protected static readonly string STATES_TAG = "states";
        protected static readonly string STATE_TAG = "state";
        protected static readonly string CODE_TAG = "code";
        protected static readonly string TRANSITION_TAG = "transition";
        protected static readonly string TRANSITION_GROUP_TAG = "transition_group";
        protected static readonly string WHILE_TAG = "while";
        protected static readonly string DO_WHILE_TAG = "do_while";
        protected static readonly string FOR_TAG = "for";
        protected static readonly string IF_TAG = "if";
        protected static readonly string ELSE_TAG = "else";
        protected static readonly string SWITCH_TAG = "switch";
        protected static readonly string CASE_TAG = "case";
        protected static readonly string DEFAULT_TAG = "default";
        protected static readonly string EXECUTE_TAG = "execute";
        protected static readonly string GET_NEXT_MESSAGE_TAG = "get_next_message";
        protected static readonly string SEND_MESSAGE_TAG = "send_message";
        protected static readonly string BREAK_TAG = "break";
        protected static readonly string CONTINUE_TAG = "continue";
        protected static readonly string RETURN_TAG = "return";

        protected static readonly string NAME_ATTRIBUTE = "name";
	    protected static readonly string REGISTER_AT_START_ATTRIBUTE = "register_at_start";
        protected static readonly string VALUE_ATTRIBUTE = "value";
        protected static readonly string TEST_ATTRIBUTE = "test";
        protected static readonly string ASSIGN_ATTRIBUTE = "assign";
        protected static readonly string STEP_ATTRIBUTE = "step";
        protected static readonly string FROM_ATTRIBUTE = "from";
        protected static readonly string TO_ATTRIBUTE = "to";
        protected static readonly string EXPRESSION_ATTRIBUTE = "expression";
        protected static readonly string TIMER_ATTRIBUTE = "timer";
        protected static readonly string DATA_ATTRIBUTE = "data";
        protected static readonly string CURRENT_STATE_ATTRIBUTE = "current_state";

        protected static readonly string GET_CURRENT_MESSAGE_FROM_FUNCTION = "getCurrentMessageFrom";
	    protected static readonly string GET_CURRENT_MESSAGE_DATA_FUNCTION = "getCurrentMessageData";
	    protected static readonly string IS_CURRENT_MESSAGE_NULL_FUNCTION = "isCurrentMessageNull";
	    protected static readonly string EXECUTE_TRANSITION_FUNCTION = "executeTransition";
	    protected static readonly string SIZE_FUNCTION = "size";
	    protected static readonly string SPLIT_FUNCTION = "split";
	    protected static readonly string PARSE_INTEGER_FUNCTION = "parseInteger";

        protected DeserializationAutomaton deserializationAutomaton = null;

        public override bool DeserializeFromString(string serialization)
        {
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serialization)))
            {
                return DeserializeFromStream(ms);
            }
        }

        public override bool DeserializeFromStream(Stream inputStream)
        {
            deserializationAutomaton = new DeserializationAutomaton(this);
            deserializationAutomaton.Start();

            XMLAutomatonDeserializer xad = new XMLAutomatonDeserializer(deserializationAutomaton);
            bool success = xad.Deserialize(inputStream);

            deserializationAutomaton.WaitForFinish();
            deserializationAutomaton = null;
            return success;
        }


        public override string SerializeToString()
        {
            using (MemoryStream outputStream = new MemoryStream())
            {
                SerializeToStream(outputStream);
                using (StreamReader sr = new StreamReader(outputStream))
                {
                    return sr.ReadToEnd();
                }
            }
        }

        public override bool SerializeToStream(Stream outputStream)
        {
            try
            {
                XMLAutomatonSerializer xas = new XMLAutomatonSerializer(this);
                return xas.Serialize(outputStream);
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
